package com.xzc.util;

import cn.hutool.core.collection.CollUtil;
import com.google.common.collect.Lists;
import com.xzc.enums.DeptNameEnums;
import com.xzc.pojo.*;
import com.xzc.pojo.response.Bug;
import com.xzc.pojo.response.Task;
import com.xzc.pojo.response.User;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author 熊志聪
 * @Classname GetStaffDataUtils
 * @Description 将禅道中获取的数据转换成打印表格bean:AllStaffTime
 * @Date 2021/12/15 16:54
 */
@Slf4j
public class GetStaffDataUtils {
    public static List<AllStaffTime> getAllStaffTime(ZenTaoValues zenTaoValues){
        List<AllStaffTime> allStaffTimes=new ArrayList<>();

        //本部门的所有用户
        List<User> usersByDept = ZenTaoUtils.getUsersByDept(zenTaoValues);
        log.info("获取本部门成员结束...");
        Map<String, User> userMap = usersByDept.stream().collect(Collectors.toMap
                (User::getAccount, Function.identity()));
        Set<String> deptUsers = usersByDept.stream().map(User::getAccount).collect(Collectors.toSet());
        //所有项目
        List<Project> allProjects = ZenTaoUtils.getAllProjects(zenTaoValues);
        log.info("获取本部门所有项目结束...");
        Map<Integer, Project> projectMap = allProjects.stream().collect(Collectors.toMap
                (Project::getId, Function.identity()));
        Map<String, Project> projectCodeMap = allProjects.stream().collect(Collectors.toMap
                (Project::getCode, Function.identity()));
        Map<String, StaffAllProjectTime> allProjectTimeMap=new HashMap<>();
        int projectSize= allProjects.size();
        for(Project project:allProjects){
            Set<String> deptUsersTemp = new HashSet<>(deptUsers);
            Set<String> projectTeamUsers = ZenTaoUtils.getTeamMember(project.getId(), zenTaoValues);
            deptUsersTemp.retainAll(projectTeamUsers);
            //当前项目的团员成员中必须包含本部门中的人
            if(CollUtil.isNotEmpty(deptUsersTemp)){
                Collection<Task> tasksByProjectId = ZenTaoUtils.getTasksByProjectId(project.getId(), zenTaoValues);
                log.info("获取项目:{}对应的任务信息结束...",project.getName());
                // 首先要进行筛选,去除任务不是本部门成员完成的任务
                for(Task task:tasksByProjectId){
                    String account= StringUtils.isNotBlank(task.getFinishedBy())?task.getFinishedBy():task.getAssignedTo();
                    User user = userMap.get(account);
                    //过滤非本部门的
                    if(user==null){
                        continue;
                    }
//                if("赵博文".equals(user.getRealname())){
//                    System.out.println(task);
//                }
                    StaffAllProjectTime projectTimeMap = allProjectTimeMap.getOrDefault(account,
                            new StaffAllProjectTime(user.getRealname(), account, getRole(zenTaoValues, user)));
                    projectTimeMap.setUserId(user.getId());
                    List<StaffProjectTime> staffProjectTimes = projectTimeMap.getStaffProjectTimes();

                    Project project1 = projectCodeMap.get(ZenTaoUtils.getProjectCodeByStoryId(task,null,zenTaoValues,projectMap));
                    boolean existedProject=false;
                    if(CollUtil.isNotEmpty(staffProjectTimes)){
                        for(StaffProjectTime staffProjectTime:staffProjectTimes){
                            if(project1.getCode().equals(staffProjectTime.getProjectCode())){
                                staffProjectTime.setWorkTime(staffProjectTime.getWorkTime().add(task.getConsumed()));
                                existedProject=true;
                                break;
                            }
                        }
                    }
//                log.info("id:{},project:{}",task.getProject(),project1);
                    if(!existedProject) {
                        staffProjectTimes.add(new StaffProjectTime(project1.getName(), project1.getCode(),task.getConsumed()));
                    }
                    allProjectTimeMap.put(account,projectTimeMap);


                }
            }else {
                log.info("当前项目:{}不包含本部门成员,不进行项目对应的任务统计",project.getName());
            }

            //-----------bug----------
            Collection<Bug> bugs = ZenTaoUtils.getBugs(project.getId(), zenTaoValues, projectMap,projectCodeMap,userMap);
            log.info("获取项目:{}对应的bug信息结束...",project.getName());
            for(Bug bug:bugs){
                String account= bug.getUserName();
                User user = userMap.get(account);
                //过滤非本部门的
                if(user==null){
                    continue;
                }
                StaffAllProjectTime projectTimeMap = allProjectTimeMap.getOrDefault(account,
                        new StaffAllProjectTime(user.getRealname(), account, getRole(zenTaoValues, user)));
                projectTimeMap.setUserId(user.getId());
                List<StaffProjectTime> staffProjectTimes = projectTimeMap.getStaffProjectTimes();

                Project project1 = projectCodeMap.get(bug.getProjectCode());
                boolean existedProject=false;
                if(CollUtil.isNotEmpty(staffProjectTimes)){
                    for(StaffProjectTime staffProjectTime:staffProjectTimes){
                        if(project1.getCode().equals(staffProjectTime.getProjectCode())){
                            staffProjectTime.setWorkTime(staffProjectTime.getWorkTime().add(bug.getWorkTime()));
                            existedProject=true;
                            break;
                        }
                    }
                }
                if(!existedProject) {
                    staffProjectTimes.add(new StaffProjectTime(project1.getName(), project1.getCode(),bug.getWorkTime()));
                }
                allProjectTimeMap.put(account,projectTimeMap);
            }
            log.info("项目:{}对应的统计工时结束...",project.getName());
            log.info("剩余{}个项目未进行统计.",--projectSize);

        }
        //没有任务信息的员工填充空信息
        for(User user:usersByDept){
            String account = user.getAccount();
            if(allProjectTimeMap.get(account)==null){
                Integer role = getRole(zenTaoValues, user);
                if(role<0){
                    continue;
                }
                StaffAllProjectTime staffAllProjectTime=new StaffAllProjectTime(user.getRealname(), account,role );
                staffAllProjectTime.setStaffProjectTimes(Collections.singletonList(StaffProjectTime.getZeroObject()));
                staffAllProjectTime.setUserId(user.getId());
                allProjectTimeMap.put(account,staffAllProjectTime);
            }
        }
        Map<Integer, List<StaffAllProjectTime>> listMap = allProjectTimeMap.values().stream().
                collect(Collectors.toMap(StaffAllProjectTime::getRole,
                        Lists::newArrayList,
                        (List<StaffAllProjectTime> newValueList, List<StaffAllProjectTime> oldValueList) -> {
                            oldValueList.addAll(newValueList);
                            return oldValueList;
                        }));
        for(DeptNameEnums deptNameEnums:DeptNameEnums.values()){
            List<StaffAllProjectTime> staffAllProjectTimes = listMap.get(deptNameEnums.getValue());
            if(CollUtil.isNotEmpty(staffAllProjectTimes)) {
                staffAllProjectTimes.sort(Comparator.comparingInt(StaffAllProjectTime::getUserId));
            }
            allStaffTimes.add(new AllStaffTime(zenTaoValues.getOneDeptName(),deptNameEnums.getName(),staffAllProjectTimes));
        }
        return allStaffTimes;
    }
    public static List<StaffTaskTime> getAllStaffTimeToMaxAndMin(ZenTaoValues zenTaoValues){
        List<StaffTaskTime> allStaffTimes=new ArrayList<>();

        //本部门的所有用户
        List<User> usersByDept = ZenTaoUtils.getUsersByDept(zenTaoValues);
        log.info("获取本部门成员结束...");
        Map<String, User> userMap = usersByDept.stream().collect(Collectors.toMap
                (User::getAccount, Function.identity()));
        Set<String> deptUsers = usersByDept.stream().map(User::getAccount).collect(Collectors.toSet());
        //所有项目
        List<Project> allProjects = ZenTaoUtils.getAllProjects(zenTaoValues);
        log.info("获取本部门所有项目结束...");
        Map<Integer, Project> projectMap = allProjects.stream().collect(Collectors.toMap
                (Project::getId, Function.identity()));
        Map<String, Project> projectCodeMap = allProjects.stream().collect(Collectors.toMap
                (Project::getCode, Function.identity()));
        int projectSize= allProjects.size();
        StaffTaskTime max=new StaffTaskTime();
        StaffTaskTime min=new StaffTaskTime();
        for(Project project:allProjects){
            Set<String> deptUsersTemp = new HashSet<>(deptUsers);
            Set<String> projectTeamUsers = ZenTaoUtils.getTeamMember(project.getId(), zenTaoValues);
            deptUsersTemp.retainAll(projectTeamUsers);
            //当前项目的团员成员中必须包含本部门中的人
            if(CollUtil.isNotEmpty(deptUsersTemp)){
                Collection<Task> tasksByProjectId = ZenTaoUtils.getTasksByProjectId(project.getId(), zenTaoValues);
                log.info("获取项目:{}对应的任务信息结束...",project.getName());
                // 首先要进行筛选,去除任务不是本部门成员完成的任务
                for(Task task:tasksByProjectId){
                    String account= StringUtils.isNotBlank(task.getFinishedBy())?task.getFinishedBy():task.getAssignedTo();
                    User user = userMap.get(account);
                    //过滤非本部门的
                    if(user==null){
                        continue;
                    }
                    if(task.getConsumed().compareTo(BigDecimal.ZERO)<=0){
                        continue;
                    }
                    if(max.getTask()==null){
                        max.setTask(task); min.setTask(task);
                        max.setStaffName(user.getRealname());min.setStaffName(user.getRealname());
                        max.setUserId(user.getId());min.setUserId(user.getId());
                        max.setAccount(user.getAccount());min.setAccount(user.getAccount());
                    }else {
                        if(max.getTask().getConsumed().compareTo(task.getConsumed())<0){
                            max.setTask(task);
                            max.setStaffName(user.getRealname());
                            max.setUserId(user.getId());
                            max.setAccount(user.getAccount());
                        }
                        if(min.getTask().getConsumed().compareTo(task.getConsumed())>0){
                            min.setTask(task);
                            min.setStaffName(user.getRealname());
                            min.setUserId(user.getId());
                            min.setAccount(user.getAccount());
                        }
                    }

                }
            }else {
                log.info("当前项目:{}不包含本部门成员,不进行项目对应的任务统计",project.getName());
            }
            log.info("项目:{}对应的统计工时结束...",project.getName());
            log.info("剩余{}个项目未进行统计.",--projectSize);

        }
        allStaffTimes.add(min);allStaffTimes.add(max);
        return allStaffTimes;
    }
    public static List<StaffTaskTime> getMaxAndMinToOneYear(ZenTaoValues zenTaoValues){
        List<StaffTaskTime> allStaffTimes=new ArrayList<>();
        StaffTaskTime max=new StaffTaskTime();
        StaffTaskTime min=new StaffTaskTime();
        int maxMonth=Calendar.getInstance().get(Calendar.MONTH) + 1;
        log.info("max:{}",maxMonth);
        for (int i = 1; i <= maxMonth; ++i) {
            zenTaoValues.setMonth(i);
            List<StaffTaskTime> allStaffTimeToMaxAndMin = getAllStaffTimeToMaxAndMin(zenTaoValues);
            if (min.getTask()==null){
                min=allStaffTimeToMaxAndMin.get(0);
            }
            if(max.getTask()==null){
                max=allStaffTimeToMaxAndMin.get(1);
            }
            if(max.getTask().getConsumed().compareTo(allStaffTimeToMaxAndMin.get(1).getTask().getConsumed())<0){
                max=allStaffTimeToMaxAndMin.get(1);
            }
            if(min.getTask().getConsumed().compareTo(allStaffTimeToMaxAndMin.get(0).getTask().getConsumed())>0){
                min=allStaffTimeToMaxAndMin.get(0);
            }
        }
        allStaffTimes.add(min);allStaffTimes.add(max);
        return allStaffTimes;
    }
    public static List<AllStaffTime> getAllStaffTimeTest(ZenTaoValues zenTaoValues){
        List<AllStaffTime> allStaffTimes=new ArrayList<>();

        //本部门的所有用户
        List<User> usersByDept = ZenTaoUtils.getUsersByDept(zenTaoValues);
        log.info("获取本部门成员结束...");
        Map<String, User> userMap = usersByDept.stream().collect(Collectors.toMap
                (User::getAccount, Function.identity()));
        //所有项目
        List<Project> allProjects = ZenTaoUtils.getAllProjects(zenTaoValues);

        log.info("获取本部门所有项目结束...");
        Map<Integer, Project> projectMap = allProjects.stream().collect(Collectors.toMap
                (Project::getId, Function.identity()));
        Map<String, Project> projectCodeMap = allProjects.stream().collect(Collectors.toMap
                (Project::getCode, Function.identity()));
        Map<String, StaffAllProjectTime> allProjectTimeMap=new HashMap<>();
        Set<String> usedProjectCode = hasUsedProjectCode();
        Set<String> usedUsers = hasUsedUsers();
        for(Project project:allProjects){
            //只选中一个项目进行测试
            if(!usedProjectCode.contains(project.getCode())){
                continue;
            }
            //每个项目中的所有的任务
            Collection<Task> tasksByProjectId = ZenTaoUtils.getTasksByProjectId(project.getId(), zenTaoValues);
            log.info("获取项目:{}对应的任务信息结束...",project.getName());

            // 首先要进行筛选,去除任务不是本部门成员完成的任务
            for(Task task:tasksByProjectId){
                String account= StringUtils.isNotBlank(task.getFinishedBy())?task.getFinishedBy():task.getAssignedTo();
                User user = userMap.get(account);
                //过滤非本部门的
                if(user==null||!usedUsers.contains(user.getRealname())){
                    continue;
                }
                StaffAllProjectTime projectTimeMap = allProjectTimeMap.getOrDefault(account,
                        new StaffAllProjectTime(user.getRealname(), account, getRole(zenTaoValues, user)));
                projectTimeMap.setUserId(user.getId());
                List<StaffProjectTime> staffProjectTimes = projectTimeMap.getStaffProjectTimes();

                Project project1 = projectCodeMap.get(ZenTaoUtils.getProjectCodeByStoryId(task,null,zenTaoValues,projectMap));
                boolean existedProject=false;
                if(CollUtil.isNotEmpty(staffProjectTimes)){
                    for(StaffProjectTime staffProjectTime:staffProjectTimes){
                        if(project1.getCode().equals(staffProjectTime.getProjectCode())){
                            staffProjectTime.setWorkTime(staffProjectTime.getWorkTime().add(task.getConsumed()));
                            existedProject=true;
                            break;
                        }
                    }
                }
                if(!existedProject) {
                    staffProjectTimes.add(new StaffProjectTime(project1.getName(), project1.getCode(),task.getConsumed()));
                }
                allProjectTimeMap.put(account,projectTimeMap);
            }

        }
        //没有任务信息的员工填充空信息
        for(User user:usersByDept){
            String account = user.getAccount();
            if(allProjectTimeMap.get(account)==null){
                Integer role = getRole(zenTaoValues, user);
                if(role<0){
                    continue;
                }
                StaffAllProjectTime staffAllProjectTime=new StaffAllProjectTime(user.getRealname(), account,role );
                staffAllProjectTime.setStaffProjectTimes(Collections.singletonList(StaffProjectTime.getZeroObject()));
                staffAllProjectTime.setUserId(user.getId());
                allProjectTimeMap.put(account,staffAllProjectTime);
            }
        }
        Map<Integer, List<StaffAllProjectTime>> listMap = allProjectTimeMap.values().stream().
                collect(Collectors.toMap(StaffAllProjectTime::getRole,
                        Lists::newArrayList,
                        (List<StaffAllProjectTime> newValueList, List<StaffAllProjectTime> oldValueList) -> {
                            oldValueList.addAll(newValueList);
                            return oldValueList;
                        }));
        for(DeptNameEnums deptNameEnums:DeptNameEnums.values()){
            List<StaffAllProjectTime> staffAllProjectTimes = listMap.get(deptNameEnums.getValue());
            if(CollUtil.isNotEmpty(staffAllProjectTimes)) {
                staffAllProjectTimes.sort(Comparator.comparingInt(StaffAllProjectTime::getUserId));
            }
            allStaffTimes.add(new AllStaffTime(zenTaoValues.getOneDeptName(),deptNameEnums.getName(),staffAllProjectTimes));
        }
        return allStaffTimes;
    }
    private static Set<String> hasUsedProjectCode(){
        Set<String> ret=new HashSet<>();
        ret.add("market_data");ret.add("ISS");ret.add("电子卖场");
        ret.add("SC-XM2021031-1");
        return ret;
    }
    private static Set<String> hasUsedUsers(){
        Set<String> ret=new HashSet<>();
        ret.add("官静萍");ret.add("袁瑞");ret.add("林登钰");
        return ret;
    }
    public static Integer getRole(ZenTaoValues zenTaoValues,User user){
        Integer role=-1;
        if(zenTaoValues.getBigDataStaffList().contains(user.getRealname())){
            return 3;
        }
        switch (user.getRole()){
            case "po":role=1;break;
            case "dev":
            case "td":role=2;break;
            case "qd":
            case "qa":role=4;break;
            default:
                log.info("该role角色不需要!");
        }
        return role;
    }
}
